package redis

import (
	"CampusCloudAid/models"
	"CampusCloudAid/settings"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"
)

// GetKey 从 Redis 中获取以特定前缀开头的键，并解析它们的 JSON 值
func GetKey(str string) ([]models.Article, error) {
	// 初始化游标
	cursor := uint64(0)

	// 创建或打开文件用于写入解析后的 JSON 数据
	file, err := os.Create("./storage/parse_data/" + str + "_DATA.json")
	if err != nil {
		log.Fatalf("Error creating file: %v", err)
		return nil, err
	}
	defer file.Close()
	file2, err := os.Create("./storage/parse_data/" + str + "_ArticleContent.json")
	if err != nil {
		log.Fatalf("Error creating file: %v", err)
		return nil, err
	}
	defer file2.Close()

	// 用于保存所有解析后的结构体
	var allResults []models.Article

	//用于保存文章部分详细内容解析后的结构体
	var articleContentSlice []models.ArticleContent
	// 使用 SCAN 命令查找以指定前缀开头的键
	for {
		// 执行 SCAN 命令
		keys, newCursor, err := client.Scan(cursor, fmt.Sprintf("%s*", str), int64(settings.Conf.CheckNum)).Result()
		if err != nil {
			log.Fatalf("Error scanning keys: %v", err)
			return nil, err
		}

		// 打印找到的键
		for _, key := range keys {
			value, err := client.Get(key).Result()
			if err != nil {
				log.Fatalf("Error getting value for key %s: %v", key, err)
				return nil, err
			}

			//接下来的操作是因为拿来的value值是一个json格式外套了一层双引号。
			// 去除外层引号
			if len(value) > 0 && value[0] == '"' && value[len(value)-1] == '"' {
				value = value[1 : len(value)-1] // 去除外层引号
			}

			// 处理转义字符
			value = unescapeJSON(value)

			//直接解析
			// 解析 JSON 字符串
			var resultArticle models.Article
			err = json.Unmarshal([]byte(value), &resultArticle)
			if err != nil {
				log.Fatalf("Error parsing JSON: %v", err)
			}
			allResults = append(allResults, resultArticle)

			//解析pdf的oss连接
			pdfOssContent := resultArticle.PdfOssJson

			var resultPdfOssContentList []models.PdfOssJson
			if len(pdfOssContent) > 0 {
				// 解析 JSON
				// 解析 JSON 字符串
				err = json.Unmarshal([]byte(pdfOssContent), &resultPdfOssContentList)
				if err != nil {
					log.Fatalf("Error parsing JSON: %v", err)
				}
				for i := range resultPdfOssContentList {
					if len(resultPdfOssContentList[i].PdfCnUrl) != 0 {
						resultPdfOssContentList[i].PdfCnUrl = fmt.Sprintf("http://diaoyan001.com/warehouse-api/zhiku/oss_filename?filename=%s", resultPdfOssContentList[i].PdfCnUrl)
					}
					if len(resultPdfOssContentList[i].PdfUrl) != 0 {
						resultPdfOssContentList[i].PdfUrl = fmt.Sprintf("http://diaoyan001.com/warehouse-api/zhiku/oss_filename?filename=%s", resultPdfOssContentList[i].PdfUrl) // 将解析后的结果添加到切片中
					}
				}
			}

			// 解析文章部分详细内容
			valueArticleContent := resultArticle.ArticleContentJson

			// 去除外层[]
			if len(valueArticleContent) > 0 && valueArticleContent[0] == '[' && valueArticleContent[len(valueArticleContent)-1] == ']' {
				valueArticleContent = valueArticleContent[1 : len(valueArticleContent)-1] // 去除外层引号
			}
			if len(valueArticleContent) > 0 {
				//直接解析
				// 解析 JSON 字符串
				var resultArticleContent models.ArticleContent

				err = json.Unmarshal([]byte(valueArticleContent), &resultArticleContent)
				if err != nil {
					log.Fatalf("Error parsing JSON: %v", err)
				}
				resultArticleContent.ArticleCode = resultArticle.ArticleCode
				resultArticleContent.ArticleUrl = resultArticle.ArticleUrl
				resultArticleContent.HTML = fmt.Sprintf("http://diaoyan001.com/warehouse-api/zhiku/oss_filename?filename=%s", resultArticleContent.HTML)
				resultArticleContent.Text = fmt.Sprintf("http://diaoyan001.com/warehouse-api/zhiku/oss_filename?filename=%s", resultArticleContent.Text)
				resultArticleContent.HTMLPro = fmt.Sprintf("http://diaoyan001.com/warehouse-api/zhiku/oss_filename?filename=%s", resultArticleContent.HTMLPro)
				resultArticleContent.ImgOssUrl = fmt.Sprintf("http://diaoyan001.com/warehouse-api/zhiku/oss_filename?filename=%s", resultArticle.ImgOssUrl)
				resultArticleContent.Pdfs = resultPdfOssContentList
				resultArticleContent.Apart1 = "------------------------------------------------------------------------------"
				resultArticleContent.Apart2 = "-----------------------以下为pdf的内容---------------------------------"

				// 将解析后的结果添加到切片中
				articleContentSlice = append(articleContentSlice, resultArticleContent)
			}

		}

		// 更新游标
		cursor = newCursor

		// 如果游标为 0，表示扫描完成
		if cursor == 0 {
			fmt.Println(str + "解析完成:--------------------------------")
			break
		}
	}
	if len(articleContentSlice) < len(allResults) {
		fmt.Println("注意注意注意注意注意：" + "部分文章是没有主题内容的")
		fmt.Printf("注意注意注意注意注意：共有%d篇文章\n", len(allResults))
		fmt.Printf("注意注意注意注意注意：其中有%d篇文章没有主题内容\n", len(allResults)-len(articleContentSlice))
	}

	// 将所有结果转换为 JSON 格式
	prettyJSON, err := json.MarshalIndent(allResults, "", "  ")
	if err != nil {
		log.Fatalf("Error marshaling all results to JSON: %v", err)
		return nil, err
	}

	// 将解析后的所有数据写入文件
	if _, err = file.Write(append(prettyJSON, '\n')); err != nil {
		log.Printf("Error writing to file: %v", err)
		return nil, err
	}
	//同样的方法把文章的部分详细内容数据也转换为json后写入文件
	prettyJSON2, err2 := json.MarshalIndent(articleContentSlice, "", "  ")
	if err2 != nil {
		log.Fatalf("Error marshaling all results to JSON: %v", err)
		return nil, err2
	}

	// 将解析后的所有数据写入文件
	if _, err2 = file2.Write(append(prettyJSON2, '\n')); err2 != nil {

		log.Printf("Error writing to file: %v", err2)
		return nil, err2
	}

	// 打印完成消息
	fmt.Printf("Search complete.redis中一共有%d条数据\n", len(allResults))
	return allResults, nil
}

// unescapeJSON 处理字符串中的转义字符
func unescapeJSON(s string) string {
	// 替换转义字符（双引号和反斜杠）
	s = strings.ReplaceAll(s, "\\\"", "\"") // 替换转义的双引号
	s = strings.ReplaceAll(s, "\\\\", "\\") // 替换转义的反斜杠
	return s
}
